namespace SimpleWebServices.Web.Mvc
{
    using System;
    using System.Collections.Specialized;
    using System.Globalization;
    using System.Net;
    using System.Threading;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Moq;
    using SimpleWebServices;
    using SimpleWebServices.Configuration;
    using SimpleWebServices.Web.Routing;
    using Xunit;

    public sealed class NotFoundControllerFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<NotFoundController>()
                .DerivesFrom<Controller>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Implements<IRegisterRoutes>()
                .IsDecoratedWith<InternalServerErrorAttribute>()
                .IsDecoratedWith<CacheControlAttribute>()
                .IsDecoratedWith<ContentLanguageAttribute>()
                .IsDecoratedWith<ContentMD5Attribute>()
                .Allow("GET, HEAD, OPTIONS")
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new NotFoundController());
        }

        [Fact]
        public void op_Register_RouteCollectionNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new NotFoundController() as IRegisterRoutes).Register(null));
        }

        [Fact]
        public void op_Register_RouteCollection()
        {
            RouteCollection routes = new RouteCollection();
            (new NotFoundController() as IRegisterRoutes).Register(routes);

            Assert.Equal<int>(2, routes.Count);
        }

        [Fact]
        public void op_HtmlRepresentation()
        {
            CultureInfo culture = Thread.CurrentThread.CurrentUICulture;

            try
            {
                var mock = new Mock<HttpContextBase>();
                mock.SetupGet<string>(x => x.Request.HttpMethod).Returns("GET").Verifiable();
                mock.SetupGet<Uri>(x => x.Request.Url).Returns(new Uri("http://example.com/path?query")).Verifiable();
                mock.SetupGet<NameValueCollection>(x => x.Request.Headers).Returns(new NameValueCollection { { "Accept", "*/*" } }).Verifiable();
                mock.SetupSet(x => x.Response.StatusCode).Callback(actual => Assert.Equal<int>(actual, (int)HttpStatusCode.NotFound)).Verifiable();
                HttpContextFactory.Mock = mock.Object;

                Default.Register<DefaultResource>("<resource />");
                Default.Register<NotFound>("<resource />");

                NotFoundController controller = new NotFoundController();
                controller.ControllerContext = new ControllerContext()
                {
                    HttpContext = mock.Object
                };

                Assert.IsType<ViewResult>(controller.HtmlRepresentation());

                mock.VerifyAll();
            }
            finally
            {
                Thread.CurrentThread.CurrentUICulture = culture;

                HttpContextFactory.Reset();
                Default.Reset();
            }
        }
    }
}